<!DOCTYPE html>
<html lang="zh_CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>《计算通信方位角和大圆距离程序》</title>
    <script src="https://cdn.ghink.net/js/vue/2.6.14/vue.min.js"></script>
    <script>
        function sgn(n) {
            if (n > 0) {
                return 1;
            } else if (n < 0) {
                return -1;
            } else {
                return 0;
            }
        }

        function fndeg(d, m, s) {
            return d + sgn(d) * (m / 60 + s/ 3600);
        }

        function fnacs(x) {
            return Math.PI / 2 - 2 * Math.atan(x / (1 + Math.sqrt(1 - x * x)));
        }

        function calc(tlongd, tlatd, rlongd, rlatd) {
            let ro = 6370;

            let gcdkm;
            let btrd;
            let brtd;

            let r2d = 180 / Math.PI;
            let d2r = Math.PI / 180;

            let tlong = tlongd * d2r;
            let tlat = tlatd * d2r;
            let rlong = rlongd * d2r;
            let rlat = rlatd * d2r;

            if (tlong < 0) {
                tlong = Math.PI * 2 + tlong;
            }
            if (rlong < 0) {
                rlong = Math.PI * 2 + rlong;
            }

            let dlong = tlong - rlong;
            if (Math.abs(dlong) > Math.PI) {
                dlong = dlong - Math.PI * 2 * sgn(dlong);
            }

            let x = Math.sin(tlat) * Math.sin(rlat) + Math.cos(tlat) * Math.cos(rlat) * Math.cos(dlong);
            let gcd = fnacs(x);

            if (gcd < 0.0000001) {
                gcd = 0.0000001;
            }

            if (Math.cos(tlat) - 0.0000001 <= 0) {
                let btr;
                if (tlat >= 0) {
                    btr = 0;
                } else {
                    btr = Math.PI;
                }

                if (Math.cos(rlat) - 0.0000001 > 0) {
                    x = (Math.sin(tlat) - Math.sin(rlat) * Math.cos(gcd)) / (Math.cos(rlat) * Math.sin(gcd));
                    let brt = fnacs(x);
                    if (dlong < 0) {
                        brt = Math.PI * 2 - brt;
                    }
                    gcdkm = gcd * ro;
                    btrd = btr * r2d;
                    brtd = brt * r2d;
                } else {
                    let brt;
                    if (rlat >= 0) {
                        brt = 0;
                    } else {
                        brt = Math.PI;
                    }
                    gcdkm = gcd * ro;
                    btrd = btr * r2d;
                    brtd = brt * r2d;
                }
            } else {
                x = (Math.sin(rlat) - Math.sin(tlat) * Math.cos(gcd)) / (Math.cos(tlat) * Math.sin(gcd));
                let btr = fnacs(x);

                if (dlong > 0) {
                    btr = Math.PI * 2 - btr;
                }

                if (Math.cos(rlat) - 0.0000001 > 0) {
                    x = (Math.sin(tlat) - Math.sin(rlat) * Math.cos(gcd)) / (Math.cos(rlat) * Math.sin(gcd));
                    let brt = fnacs(x);
                    if (dlong < 0) {
                        brt = Math.PI * 2 - brt;
                    }
                    gcdkm = gcd * ro;
                    btrd = btr * r2d;
                    brtd = brt * r2d;
                } else {
                    let brt;
                    if (rlat >= 0) {
                        brt = 0;
                    } else {
                        brt = Math.PI;
                    }
                    gcdkm = gcd * ro;
                    btrd = btr * r2d;
                    brtd = brt * r2d;
                }
            }

            return [gcdkm, btrd, brtd];
        }
    </script>
</head>
<body>
    <h1>计算通信方位角和大圆距离程序</h1>
    <div id="app">
        <p>
            发信点经度（度，分，秒）
            <input type="number" v-model="tlongdd" max="180" min="-180" placeholder="度" style="width:40px; height:20px;">
            <input type="number" v-model="tlongdm" max="60" min="-60" placeholder="分" style="width:40px; height:20px;">
            <input type="number" v-model="tlongds" max="60" min="-60" placeholder="秒" style="width:40px; height:20px;">
        </p>
        <p>
            发信点纬度（度，分，秒）
            <input type="number" v-model="tlatdd" max="90" min="-90" placeholder="度" style="width:40px; height:20px;">
            <input type="number" v-model="tlatdm" max="60" min="-60" placeholder="分" style="width:40px; height:20px;">
            <input type="number" v-model="tlatds" max="60" min="-60" placeholder="秒" style="width:40px; height:20px;">
        </p>
        <p>
            收信点经度（度，分，秒）
            <input type="number" v-model="rlongdd" max="180" min="-180" placeholder="度" style="width:40px; height:20px;">
            <input type="number" v-model="rlongdm" max="60" min="-60" placeholder="分" style="width:40px; height:20px;">
            <input type="number" v-model="rlongds" max="60" min="-60" placeholder="秒" style="width:40px; height:20px;">
        </p>
        <p>
            收信点纬度（度，分，秒）
            <input type="number" v-model="rlatdd" max="90" min="-90" placeholder="度" style="width:40px; height:20px;">
            <input type="number" v-model="rlatdm" max="60" min="-60" placeholder="分" style="width:40px; height:20px;">
            <input type="number" v-model="rlatds" max="60" min="-60" placeholder="秒" style="width:40px; height:20px;">
        </p>
        <p>大圆距离为{{gcdkm}}(km)</p>
        <p>发信点对收信点的方位角为{{btrdd}}度{{btrdm}}分{{btrds}}秒</p>
        <p>收信点对发信点的方位角为{{brtdd}}度{{brtdm}}分{{brtds}}秒</p>
    </div>

    <script>
        function result(object) {
            let tlongd = fndeg(parseInt(object.tlongdd), parseInt(object.tlongdm), parseInt(object.tlongds))
            let tlatd = fndeg(parseInt(object.tlatdd), parseInt(object.tlatdm), parseInt(object.tlatds))
            let rlongd = fndeg(parseInt(object.rlongdd), parseInt(object.rlongdm), parseInt(object.rlongds))
            let rlatd = fndeg(parseInt(object.rlatdd), parseInt(object.rlatdm), parseInt(object.rlatds))
            return calc(tlongd, tlatd, rlongd, rlatd)
        }
        
        new Vue({
            el: '#app',
            data: {
                tlongdd: 103,
                tlongdm: 45,
                tlongds: 0,
                tlatdd: 36,
                tlatdm: 2,
                tlatds: 0,
                rlongdd: 121,
                rlongdm: 29,
                rlongds: 0,
                rlatdd: 31,
                rlatdm: 14,
                rlatds: 0
            },
            computed: {
                gcdkm: function () {
                    return result(this)[0]
                },
                btrdd: function () {
                    let d = Math.trunc(result(this)[1])
                    return d
                },
                btrdm: function () {
                    let d = Math.trunc(result(this)[1])
                    let m = Math.trunc((result(this)[1] - d) * 60)
                    return m
                },
                btrds: function () {
                    let d = Math.trunc(result(this)[1])
                    let m = Math.trunc((result(this)[1] - d) * 60)
                    let s = (result(this)[1] - d - m / 60) * 3600
                    return s
                },
                brtdd: function () {
                    let d = Math.trunc(result(this)[2])
                    let m = Math.trunc((result(this)[2] - d) * 60)
                    return d
                },
                brtdm: function () {
                    let d = Math.trunc(result(this)[2])
                    let m = Math.trunc((result(this)[2] - d) * 60)
                    return m
                },
                brtds: function () {
                    let d = Math.trunc(result(this)[2])
                    let m = Math.trunc((result(this)[2] - d) * 60)
                    let s = (result(this)[2] - d - m / 60) * 3600
                    return s
                }
            }
        })
    </script>
</body>
</html>